package com.aaa.jvmtest.classload.init;

/**
 * 验证是否初始化
 *
 * @author Tu
 * @date 2022/9/4 17:26
 */
public class InitShow {

    //main方法所在类会首先初始化
    static {
        System.out.println("main init");
    }

    //静态代码块没有执行，证明没有初始化
    public static void main(String[] args) throws ClassNotFoundException {
        //TODO 会初始化
        //1:首次访问该类静态变量或静态方法
        //System.out.println(A.a);

        //2:子类初始化，如果父类还没初始化。会先初始化父类
        //System.out.println(B.c);

        //3:子类访问父类静态变量，只触发父类初始化
        //System.out.println(B.a);

        //4:class.forName会初始化B，并且先初始化类A
        //Class.forName("com.aaa.jvmtest.classload.init.B");


        //TODO 不会初始化
        //1:静态变量不会触发初始化，    （访问final static 基本类型静态常量不会触发，字符串也不会，在常量池中）
        //System.out.println(B.b);

        //2:类对象.class不会触发初始化，   （因为类.class在加载阶段就已经生成_mirror_class在堆中，所以不会在初始化阶段完成）
        //System.out.println(B.class);

        //3:创建该类的数组不会触发初始化
        //System.out.println(new B[0]);

        //4:不会初始化B，但会加载B、A    (ClassLoader只会对类加载，不会解析和初始化)
        //ClassLoader c1 = Thread.currentThread().getContextClassLoader();
        //c1.loadClass("com.aaa.jvmtest.classload.init.B");

        //5:不会初始化类B，但会加载B、A   (Class.forName会触发，但是第二个参数是否初始化，false关闭就不会初始化)
        //ClassLoader c2 = Thread.currentThread().getContextClassLoader();
        //Class.forName("com.aaa.jvmtest.classload.init.B", false, c2);
    }
}

class A {
    static int a = 0;

    static {
        System.out.println("a init");
    }
}

class B extends A {
    final static double b = 5.0;
    static boolean c = false;

    static {
        System.out.println("b init");
    }
}

